package com.fornknow.reflection;

import java.awt.*;
import java.lang.reflect.Method;
import java.util.Hashtable;

/**
 * Java反射机制是Java语言中的一个非常重要的特性，它具有动态机制-------反射
 * 反射特点：
 * 1.在程序运行的时候会判断任意一个对象所属的类
 * 2.在运行的时候获取类的对象
 * 3.在运行的时候获取到类所具有的成员变量和方法
 *
 * 总结：通过运行结果可以发现，Java的反射机制使得在运行的时候能够判断一个对象所属的类，获取对象的方法
 * 进行调用，并可以获取方法的返回结果
 *
 * 实例化Class类对象有以下几种方式
 * 1.前提：已知是一个具体的类，大家可以通过class属性来获取，这种方法是最安全的，并且性能高
 *      Clss clazz=String.class   Mabtis中获取类对象： UserMapper.class
 * 2.前提创建一个类对象  然后   对象.getclass();
 *          Button btn =new Button();
 *          Class btnClass = btn.getClass();
 * 3.Class clazz =Class.forName("java.lang.String")
 *
 * 4.ClassLoader cl = this.getClass().getClassLoader();
 * Class clazz=cl.loadClass("全类名")
 */

public class ReflectionDemo {
    public  void getNameTest() throws ClassNotFoundException {
        String name="这是一个反射测试";
        Class c = name.getClass();
        System.out.println(c.getName());
        Button btn =new Button();
        Class btnClass = btn.getClass();
        System.out.println("这是一个Buttn类名"+btnClass.getName());
        Class superclass = btnClass.getSuperclass();
        System.out.println("Buttn父类的名字"+superclass);
        Class clsTest = Class.forName("java.awt.Button");
        System.out.println("clsTest name:"+clsTest.getName());
    }

    /**
     * 此方法可以通过反射机制去调用testMeshod方法，而无需手动调用
     * @throws Exception
     */
    public  void  getMethodTest()throws Exception{
        Class cls = Class.forName("com.fornknow.reflection.ReflectionDemo");
        Class ptyes[] =new Class[2];
        ptyes[0]=Class.forName("java.lang.String");
        ptyes[1]=Class.forName("java.util.Hashtable");
        //此方法是获取到我们想要调用的方法的名(methodName)称以及参数的类型（parameterType）
        Method method = cls.getMethod("testMethod", ptyes);
        Object[] args=new Object[2];
        args[0]="hello tom";
        Hashtable<String ,String> ht=new Hashtable<String, String>();
        ht.put("name","你好这是一个map");
        args[1]=ht;
        //我们需要调用testMesthod这个方法
        String invoke = (String) method.invoke(new ReflectionDemo(), args);
        System.out.println("returnStr="+invoke);
    }

    public String testMethod(String str, Hashtable ht)throws  Exception{
        String returnStr="这是方法的返回值";
        System.out.println("测试testMethod()方法调用");
        System.out.println("str="+str);
        System.out.println("名字="+(String) ht.get("name"));
        System.out.println("结束了testMethod()方法调用");
        return returnStr;
    }

    public static void main(String[] args) throws Exception {
        ReflectionDemo reflectionDemo = new ReflectionDemo();
            reflectionDemo.getNameTest();
       reflectionDemo.getMethodTest();
    }
}
